home *** CD-ROM | disk | FTP | other *** search
- /* highlight.c -- Highlight C source with colors.
- Copyright (C) 1995 Sandro Sigala - <sansig@freenet.hut.fi> */
-
- /* $Id: highlight.c,v 1.32 1995/08/08 12:28:25 sandro Exp $ */
-
- /* This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <getopt.h>
-
- #include "lex.h"
- #include "misc.h"
-
- #include "version.h"
-
- FILE *input_file;
- FILE *output_file;
-
- enum {
- UNBINDED = LEX_LAST_TOKEN + 1,
- NEWLINE, HORIZONTAL_TAB, VERTICAL_TAB, FORM_FEED, CARRIAGE_RETURN
- };
-
- #include "highlight.h"
-
- #define TABLE_SIZE 512
-
- static struct { int fg, bg; char *escape; } color_table[TABLE_SIZE];
-
- static int last_token = 0;
-
- static void
- color_table_set_color (int token, int fg, int bg)
- {
- char buf[128];
-
- if (color_table[token].escape != NULL)
- free (color_table[token].escape);
-
- color_table[token].fg = fg;
- color_table[token].bg = bg;
-
- sprintf (buf, "\033[%dm", fg);
- if (bg != COLOR_UNCHANGED)
- sprintf (&buf[strlen (buf) - 1], ";%dm", bg);
-
- color_table[token].escape = (char *) xmalloc (strlen (buf) + 1);
- strcpy (color_table[token].escape, buf);
- }
-
- static void
- color_table_free (void)
- {
- int i;
- for (i = 0; i < TABLE_SIZE; i++)
- if (color_table[i].escape != NULL)
- free (color_table[i].escape);
- }
-
- static void
- color_table_init (void)
- {
- int i;
- for (i = 0; i < TABLE_SIZE; i++)
- {
- color_table[i].fg = 0;
- color_table[i].bg = 0;
- color_table[i].escape = NULL;
- }
- }
-
- static void
- color_table_setup (void)
- {
- int i = 0;
-
- while (def_color_table[i].token != -1)
- {
- color_table_set_color (def_color_table[i].token,
- def_color_table[i].fg,
- def_color_table[i].bg);
- i++;
- }
- }
-
- static void
- outstr (char *s)
- {
- while (*s)
- fputc (*s++, output_file);
- }
-
- static void
- parse (void)
- {
- int tk;
- while ((tk = gettoken ()) != EOF)
- {
- if (color_table[tk].escape != NULL)
- {
- if (color_table[tk].fg != color_table[last_token].fg ||
- color_table[tk].bg != color_table[last_token].bg)
- outstr (color_table[tk].escape);
- }
- else
- outstr (color_table[UNBINDED].escape);
-
- switch (tk)
- {
- case IDENTIFIER: case NUMBER:
- case COMMENT: case DIRECTIVE: case STRING: case CHARACTER:
- case KW_AUTO: case KW_BREAK: case KW_CASE: case KW_CHAR:
- case KW_CONST: case KW_CONTINUE: case KW_DEFAULT: case KW_DO:
- case KW_DOUBLE: case KW_ELSE: case KW_ENUM: case KW_EXTERN:
- case KW_FLOAT: case KW_FOR: case KW_GOTO: case KW_IF:
- case KW_INT: case KW_LONG: case KW_REGISTER: case KW_RETURN:
- case KW_SHORT: case KW_SIGNED: case KW_SIZEOF: case KW_STATIC:
- case KW_STRUCT: case KW_SWITCH: case KW_TYPEDEF: case KW_UNION:
- case KW_UNSIGNED: case KW_VOID: case KW_VOLATILE: case KW_WHILE:
- outstr (lex_token_buffer);
- break;
-
- case TK_DECREMENT: outstr ("--"); break;
- case TK_INCREMENT: outstr ("++"); break;
- case TK_ADD_ASSIGN: outstr ("+="); break;
- case TK_SUB_ASSIGN: outstr ("-="); break;
- case TK_MUL_ASSIGN: outstr ("*="); break;
- case TK_DIV_ASSIGN: outstr ("/="); break;
- case TK_MOD_ASSIGN: outstr ("%="); break;
- case TK_AND_ASSIGN: outstr ("&="); break;
- case TK_OR_ASSIGN: outstr ("|="); break;
- case TK_XOR_ASSIGN: outstr ("^="); break;
- case TK_LEFT_ASSIGN: outstr ("<<="); break;
- case TK_RIGHT_ASSIGN: outstr (">>="); break;
- case TK_PTR_OP: outstr ("->"); break;
- case TK_EQ_OP: outstr ("=="); break;
- case TK_NE_OP: outstr ("!="); break;
- case TK_AND_OP: outstr ("&&"); break;
- case TK_OR_OP: outstr ("||"); break;
- case TK_GE_OP: outstr (">="); break;
- case TK_LE_OP: outstr ("<="); break;
- case TK_LEFT_OP: outstr ("<<"); break;
- case TK_RIGHT_OP: outstr (">>"); break;
- case TK_ELLIPSIS: outstr ("..."); break;
-
- default:
- putc (tk, output_file);
- }
- last_token = tk;
- }
- }
-
- static void
- helppage (char *progname)
- {
- fprintf (stderr, "\
- %s %s - c-tools %s - Copyright (C) 1995 Sandro Sigala.\n\
- usage: %s [-hd] [input [output]]\n\
- -h display this help and exit\n\
- -d tread directives as single characters\n\
- ", progname, VERSION_HIGHLIGHT, VERSION_CTOOLS, progname);
- exit (0);
- }
-
- int
- main (int argc, char *argv[])
- {
- int c;
-
- lex_return_white_spaces = 1;
- lex_return_directives = 1;
-
- while (1)
- {
- c = getopt (argc, argv, "hd");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case 'd':
- lex_return_directives = 0;
- break;
-
- case 'h':
- case '?':
- helppage (argv[0]);
- break;
- }
- }
-
- input_file = stdin;
- output_file = stdout;
-
- if (optind < argc)
- {
- if ((argc - optind) > 2)
- helppage (argv[0]);
-
- if (strcmp (argv[optind], "-") != 0)
- input_file = fopen (argv[optind], "r");
-
- if ((argc - optind) > 1)
- if (strcmp (argv[optind + 1], "-") != 0)
- output_file = fopen (argv[optind + 1], "w");
- }
-
- if (input_file == NULL)
- {
- fprintf (stderr, "%s: cannot open input file\n", argv[0]);
- exit (1);
- }
-
- if (output_file == NULL)
- {
- fprintf (stderr, "%s: cannot open output file\n", argv[0]);
- exit (1);
- }
-
- init_lex ();
-
- color_table_init ();
- color_table_setup ();
-
- parse ();
-
- color_table_free ();
-
- done_lex ();
-
- return 0;
- }
-
- /* highlight.c ends here */
-